using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(ActiveWeapon))]
[RequireComponent(typeof(FireWeaponEvent))]
[RequireComponent(typeof(ReloadWeaponEvent))]
[RequireComponent(typeof(WeaponFiredEvent))]
[DisallowMultipleComponent]
public class FireWeapon : MonoBehaviour
{
    private float firePreChargeTimer = 0f;
    private float fireRateCoolDownTimer = 0f;
    private ActiveWeapon activeWeapon;
    private FireWeaponEvent fireWeaponEvent;
    private ReloadWeaponEvent reloadWeaponEvent;
    private WeaponFiredEvent weaponFiredEvent;

    private void Awake()
    {
        //加载组件
        activeWeapon = GetComponent<ActiveWeapon>();
        fireWeaponEvent = GetComponent<FireWeaponEvent>();
        reloadWeaponEvent = GetComponent<ReloadWeaponEvent>();
        weaponFiredEvent = GetComponent<WeaponFiredEvent>();
    }

    private void OnEnable()
    {
        // 订阅开火事件.
        fireWeaponEvent.OnFireWeapon += FireWeaponEvent_OnFireWeapon;
    }

    private void OnDisable()
    {
        // 取消订阅开火事件.
        fireWeaponEvent.OnFireWeapon -= FireWeaponEvent_OnFireWeapon;
    }

    private void Update()
    {
        // 减少冷却计时器。
        fireRateCoolDownTimer -= Time.deltaTime;
    }

    /// <summary>
    /// 处理开火事件。
    /// </summary>
    private void FireWeaponEvent_OnFireWeapon(FireWeaponEvent fireWeaponEvent, FireWeaponEventArgs fireWeaponEventArgs)
    {
        WeaponFire(fireWeaponEventArgs);
    }

    /// <summary>
    /// Fire weapon.
    /// </summary>
    private void WeaponFire(FireWeaponEventArgs fireWeaponEventArgs)
    {
        // 手持武器预充能计时器。
        WeaponPreCharge(fireWeaponEventArgs);

        // 武器射击.
        if (fireWeaponEventArgs.fire)
        {
            // 测试武器是否准备好开火。
            if (IsWeaponReadyToFire())
            {
                FireAmmo(fireWeaponEventArgs.aimAngle, fireWeaponEventArgs.weaponAimAngle,
                    fireWeaponEventArgs.weaponAimDirectionVector);

                ResetCoolDownTimer();

                ResetPrechargeTimer();
            }
        }
    }

    /// <summary>
    /// 处理武器预装弹药。
    /// </summary>
    private void WeaponPreCharge(FireWeaponEventArgs fireWeaponEventArgs)
    {
        // 武器预装。
        if (fireWeaponEventArgs.firePreviousFrame)
        {
            // 如果触发按钮按住上一帧，请减少预充能计时器。
            firePreChargeTimer -= Time.deltaTime;
        }
        else
        {
            // 否则重置预充能计时器。
            ResetPrechargeTimer();
        }
    }

    /// <summary>
    /// 如果武器已准备好开火，则返回 true，否则返回 false。
    /// </summary>
    private bool IsWeaponReadyToFire()
    {
        // 如果没有弹药并且武器没有无限弹药，则返回 false。
        if (activeWeapon.GetCurrentWeapon().weaponRemainingAmmo <= 0 &&
            !activeWeapon.GetCurrentWeapon().weaponDetails.hasInfiniteAmmo)
            return false;

        // 如果武器正在重新装填，则返回 false。
        if (activeWeapon.GetCurrentWeapon().isWeaponReloading)
            return false;

        // 如果武器没有预充电或正在冷却，则返回 false。
        if (firePreChargeTimer > 0f || fireRateCoolDownTimer > 0f)
            return false;

        // 如果弹夹中没有弹药，并且武器没有无限弹夹容量，则返回 false。
        if (!activeWeapon.GetCurrentWeapon().weaponDetails.hasInfiniteClipCapacity &&
            activeWeapon.GetCurrentWeapon().weaponClipRemainingAmmo <= 0)
        {
            // 触发装填武器事件。
            reloadWeaponEvent.CallReloadWeaponEvent(activeWeapon.GetCurrentWeapon(), 0);

            return false;
        }

        // 武器已准备好开火 - 返回真
        return true;
    }

    /// <summary>
    /// 使用对象池中的弹药游戏对象和组件设置弹药。
    /// </summary>
    private void FireAmmo(float aimAngle, float weaponAimAngle, Vector3 weaponAimDirectionVector)
    {
        AmmoDetailsSO currentAmmo = activeWeapon.GetCurrentAmmo();

        if (currentAmmo != null)
        {
            // 射击弹药例程。
            StartCoroutine(FireAmmoRoutine(currentAmmo, aimAngle, weaponAimAngle, weaponAimDirectionVector));
        }
    }

    /// <summary>
    /// 如果在弹药详细信息中指定，则每次射击生成多个弹药的协程
    /// </summary>
    private IEnumerator FireAmmoRoutine(AmmoDetailsSO currentAmmo, float aimAngle, float weaponAimAngle,
        Vector3 weaponAimDirectionVector)
    {
        int ammoCounter = 0;

        // 每次射击获得随机弹药
        int ammoPerShot = Random.Range(currentAmmo.ammoSpawnAmountMin, currentAmmo.ammoSpawnAmountMax + 1);

        // 获取弹药之间的随机间隔
        float ammoSpawnInterval;

        if (ammoPerShot > 1)
        {
            ammoSpawnInterval = Random.Range(currentAmmo.ammoSpawnIntervalMin, currentAmmo.ammoSpawnIntervalMax);
        }
        else
        {
            ammoSpawnInterval = 0f;
        }

        // 每次射击的弹药数量循环
        while (ammoCounter < ammoPerShot)
        {
            ammoCounter++;

            // 从数组中获取弹药预制件
            GameObject ammoPrefab = currentAmmo.ammoPrefabArray[Random.Range(0, currentAmmo.ammoPrefabArray.Length)];

            // 获取随机速度值
            float ammoSpeed = Random.Range(currentAmmo.ammoSpeedMin, currentAmmo.ammoSpeedMax);

            // 使用 IFireable 组件获取游戏对象
            IFireable ammo = (IFireable)PoolManager.Instance.ReuseComponent(ammoPrefab, activeWeapon.GetShootPosition(),
                Quaternion.identity);

            // 初始化弹药
            ammo.InitialiseAmmo(currentAmmo, aimAngle, weaponAimAngle, ammoSpeed, weaponAimDirectionVector);

            // 等待每次射击的弹药时间间隔
            yield return new WaitForSeconds(ammoSpawnInterval);
        }

        // 如果不是无限的弹夹容量，则减少弹药夹数量
        if (!activeWeapon.GetCurrentWeapon().weaponDetails.hasInfiniteClipCapacity)
        {
            activeWeapon.GetCurrentWeapon().weaponClipRemainingAmmo--;
            activeWeapon.GetCurrentWeapon().weaponRemainingAmmo--;
        }

        // 调用武器发射事件
        weaponFiredEvent.CallWeaponFiredEvent(activeWeapon.GetCurrentWeapon());

        // 显示武器射击效果
        WeaponShootEffect(aimAngle);

        // 武器发射音效
        WeaponSoundEffect();
    }

    /// <summary>
    /// 重置冷却计时器
    /// </summary>
    private void ResetCoolDownTimer()
    {
        // 重置冷却计时器
        fireRateCoolDownTimer = activeWeapon.GetCurrentWeapon().weaponDetails.weaponFireRate;
    }

    /// <summary>
    /// 重置预充能计时器
    /// </summary>
    private void ResetPrechargeTimer()
    {
        // 重置预充能计时器
        firePreChargeTimer = activeWeapon.GetCurrentWeapon().weaponDetails.weaponPrechargeTime;
    }

    /// <summary>
    /// 显示武器射击效果
    /// </summary>
    private void WeaponShootEffect(float aimAngle)
    {
        // 如果有发射效果和预制件，请处理
        if (activeWeapon.GetCurrentWeapon().weaponDetails.weaponShootEffect != null &&
            activeWeapon.GetCurrentWeapon().weaponDetails.weaponShootEffect.weaponShootEffectPrefab != null)
        {
            // 使用粒子系统组件从池中获取武器射击效果游戏对象
            WeaponShootEffect weaponShootEffect = (WeaponShootEffect)PoolManager.Instance.ReuseComponent(
                activeWeapon.GetCurrentWeapon().weaponDetails.weaponShootEffect.weaponShootEffectPrefab,
                activeWeapon.GetShootEffectPosition(), Quaternion.identity);

            // 设置拍摄效果
            weaponShootEffect.SetShootEffect(activeWeapon.GetCurrentWeapon().weaponDetails.weaponShootEffect, aimAngle);

            // 将游戏对象设置为活动（粒子系统设置为自动禁用
            // 游戏物体在完成时）
            weaponShootEffect.gameObject.SetActive(true);
        }
    }

    /// <summary>
    /// 播放武器射击音效
    /// </summary>
    private void WeaponSoundEffect()
    {
        if (activeWeapon.GetCurrentWeapon().weaponDetails.weaponFiringSoundEffect != null)
        {
            SoundEffectManager.Instance.PlaySoundEffect(activeWeapon.GetCurrentWeapon().weaponDetails
                .weaponFiringSoundEffect);
        }
    }
}